perm filename DD4A.SAI[MF,ALS] blob
sn#799015 filedate 1985-07-15 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 GF input procedures: GF_INIT, SET_GF_POS, GET_GF_NEXT, GET_GF_INT, GET_GF_PREV
C00009 ENDMK
C⊗;
Comment GF input procedures: GF_INIT, SET_GF_POS, GET_GF_NEXT, GET_GF_INT, GET_GF_PREV;
! These procedures implement buffered byte I/O from the GF files. This
method of handling the GF information is used to permit the easy
translation of GF information into the raster form that was used to
store PXL information so that much of the earlier code for DVIDD
could be retained intact. The following statements describe the
meaning of various variables:
The "current byte position" is a number between 0 and 4*GFLENGTH-1.
The "current byte" is the byte at the current byte position.
The "previous byte" is the byte before the current byte.;
saf string array gf_farray[0:2]; ! Parts of the filename;
saf integer array gfblock[0:127]; ! Holds record containing previous byte;
integer gfbytenum; ! The current byte position;
string gffname; ! Name of the GF file;
integer gflength; ! Length of the GF file, in words;
integer gfrecnum; ! The record number in the GF file containing
the previous byte. (First record is 1, not 0.);
integer gfword; ! Holds the word containing the previous byte,
rotated so that previous byte is in bits 29-36;
integer gfwordnum; ! The index in GFBLOCK of the word containing
the previous byte;
! GF_INIT initializes the variables to dummy values, to force the right
thing to happen the first time SET_GF_POS or GET_GF_NEXT is called.;
simple procedure gf_init;
begin "gf_init"
gfbytenum ← 0;
gfrecnum ← 0;
gfwordnum ← 127;
end "gf_init";
require gf_init initialization;
! SET_GF_POS sets the current byte position in the GF file to the byte position
given as its argument.;
simple procedure set_gf_pos(integer bytepos);
begin "setgfpos"
integer record;
! We read in the record containing the PREVIOUS byte, so that GET_GF_NEXT
and GET_GF_PREV will work correctly. This causes a wasted read whenever
BYTEPOS is exactly at the beginning of a record, but so what.;
if bytepos = 0 then begin
useti(gfchan,1); ! go to beginning of file;
gf_init; ! set dummy values;
return
end;
gfbytenum ← bytepos;
bytepos ← bytepos - 1; ! point to previous byte;
record ← bytepos div (4*128) + 1;
if gfrecnum ≠ record then begin
useti(gfchan,record);
arryin(gfchan,gfblock[0],128);
gfrecnum ← record;
end;
gfwordnum ← (bytepos mod (4*128)) div 4;
gfword ← gfblock[gfwordnum] rot (8*(bytepos land 3 + 1));
end "setgfpos";
! GETGFNEXT returns the current byte in the GF file, and then increments the
current byte position.;
simple integer procedure get_gf_next;
begin "getgfnext"
if gfbytenum land 3 = 0 then begin
! Get new word;
if (gfwordnum ← gfwordnum + 1) = 128 then begin
! Read in next record;
arryin(gfchan,gfblock[0],128);
gfrecnum ← gfrecnum + 1;
gfwordnum ← 0;
end;
gfword ← gfblock[gfwordnum];
end;
gfword ← gfword rot 8; ! put next byte in lowest positions;
gfbytenum ← gfbytenum+1; ! number of the byte to be accessed next;
return(gfword land '377)
end "getgfnext";
define gf_bites2 = {((get_gf_next lsh 8) lor get_gf_next)},
gf_bites3 = {((gf_bites2 lsh 8) lor get_gf_next)},
gf_bites4 = {((gf_bites3 lsh 8) lor get_gf_next)};
define gf_twobites = {((gf_bites2 lsh 20) ash -20)},
gf_threebites = {((gf_bites3 lsh 12) ash -12)},
gf_fourbites = {((gf_bites4 lsh 4) ash -4)};
! Thus, a bite will fetch you some fresh bits (two,three and fourbites
give the equivalent in rsu's);
integer procedure get_gf_int; return((gf_bites4 lsh 4) ash -4);
! GET_GF_PREV decrements the current byte position, and then returns the current
byte.;
simple integer procedure get_gf_prev;
begin "get_gf_prev"
integer result;
result ← gfword land '377;
gfword ← gfword rot -8;
if (gfbytenum ← gfbytenum - 1) land 3 = 0 then set_gf_pos(gfbytenum);
! set_gf_pos is called when the (new) previous byte is in a different word,
to load that word into GFWORD.;
return(result)
end "get_gf_prev";